#ifndef PLAYER_MANAGER_H
#define PLAYER_MANAGER_H

#include <cstdint>
#include <future>
#include <queue>
#include <map>
#include <random>
#include <set>
#include <list>
#include <shared_mutex>
#include "napi/native_api.h"
#include "player.h"
#include "av_codec_sample_log.h"
#include "dfx/error/av_codec_sample_error.h"

#undef LOG_TAG
#define LOG_TAG "PLAYERMANAGER"

class PlayerManager {
private:
    PlayerManager() : currentInstanceId(-1), currentWindow(nullptr) {}

    std::map<int, int64_t> videoPositions;
    std::shared_ptr<Player> currentPlayer;
    int currentInstanceId;
    OHNativeWindow *currentWindow;
    mutable std::mutex mutex;

public:
    static napi_value Swipe(napi_env env, napi_callback_info info);
    static napi_value Start(napi_env env, napi_callback_info info);
    static napi_value Pause(napi_env env, napi_callback_info info);
    static napi_value Kill(napi_env env, napi_callback_info info);
    static napi_value Resume(napi_env env, napi_callback_info info);
    static napi_value Seek(napi_env env, napi_callback_info info);

    PlayerManager(const PlayerManager &) = delete;
    PlayerManager &operator=(const PlayerManager &) = delete;

    static PlayerManager &getInstance() {
        static std::mutex mutex;
        std::lock_guard<std::mutex> lock(mutex);
        static std::unique_ptr<PlayerManager> instancePtr;
        if (!instancePtr) {
            instancePtr.reset(new PlayerManager());
        }
        return *instancePtr;
    }

    void CreatePlayer(SampleInfo &sampleInfo) {
        if (currentPlayer) {
            currentPlayer->Kill();
        }
        currentPlayer = std::make_shared<Player>(sampleInfo.videoId, sampleInfo.window);
        currentPlayer->Init(sampleInfo);
        currentInstanceId = sampleInfo.videoId;
        currentWindow = sampleInfo.window;
        auto it = videoPositions.find(currentInstanceId);
        if (it != videoPositions.end()) {
            currentPlayer->Seek(it->second);
        }
    }

    void Swipe(SampleInfo &sampleInfo) {
        std::lock_guard<std::mutex> lock(mutex);
        // 如果当前有活跃的播放器实例，记录其播放位置
        if (currentPlayer) {
            currentPlayer->Pause(); // 暂停当前播放
            // 记录当前播放位置，这里假设我们有一个全局的映射来记录每个视频ID的播放位置
            videoPositions[currentPlayer->GetInstanceId()] = currentPlayer->GetCurrentPosition();
        }
        CreatePlayer(sampleInfo);
    }

    int32_t Start() {
        if(currentPlayer) {
            return currentPlayer->Start();
        }
        return AVCODEC_SAMPLE_ERR_ERROR;
    }
    
    int32_t WaitForDone() {
        if(currentPlayer) {
            return currentPlayer->WaitForDone();
        }
        return AVCODEC_SAMPLE_ERR_ERROR;
    }
    
    int32_t Pause() {
        if(currentPlayer) {
            return currentPlayer->Pause();
        }
        return AVCODEC_SAMPLE_ERR_ERROR;
    }
    
    int32_t Resume() {
        if(currentPlayer) {
            return currentPlayer->Resume();
        }
        return AVCODEC_SAMPLE_ERR_ERROR;
    }
    
    int32_t Seek(int64_t position) {
        if(currentPlayer) {
            return currentPlayer->Seek(position);
        }
        return AVCODEC_SAMPLE_ERR_ERROR;
    }

    void Kill() {
        std::lock_guard<std::mutex> lock(mutex);
        if (currentPlayer) {
            currentPlayer->Kill();
//             currentPlayer->releasePromise.get_future().wait();
//             currentPlayer.reset();
        }
        if (currentWindow) {
            OH_NativeWindow_DestroyNativeWindow(currentWindow);
            currentWindow = nullptr;
        }
    }
    //     PlayerManager() : currentInstanceId(-1), currentWindow(nullptr) {}
    //
    //     std::map<int32_t, std::shared_ptr<Player>> instances;
    //     std::map<int32_t, std::shared_ptr<Player>> cache;
    //     std::queue<int32_t> instanceCache;
    //     int currentInstanceId;
    //     OHNativeWindow* currentWindow;
    //     mutable std::mutex mutex;
    //
    //     int generateNewInstanceId() {
    //         std::lock_guard<std::mutex> lock(mutex);
    //         static int32_t nextId = 0; // 确保线程安全
    //         return ++nextId;
    //     }
    //
    //     void cacheInstance(int id) {
    //         std::lock_guard<std::mutex> lock(mutex);
    //         auto instance = instances.find(id);
    //         if(instance != instances.end()){
    //             instance->second->Pause();
    //             cache[id] = std::move(instance->second);
    //             instanceCache.push(id);
    //             instances.erase(instance);
    //         }
    //     }
    //
    //     int GetPreviousInstanceId() {
    //         std::lock_guard<std::mutex> lock(mutex);
    //         if (!instanceCache.empty()) {
    //             int prevInstanceId = instanceCache.front();
    //             instanceCache.pop();
    //             return prevInstanceId;
    //         }
    //         return -1;
    //     }
    //
    //     void destroyWindow(OHNativeWindow* window) {
    //         if(window != nullptr){
    //             OH_NativeWindow_DestroyNativeWindow(window);
    //             window = nullptr;
    //         }
    //     }
    //
    //     void manageInstanceLimit() {
    //         std::lock_guard<std::mutex> lock(mutex);
    //         while (instances.size() > 10) {
    //             int oldestInstanceId = instanceCache.front();
    //             instanceCache.pop();
    //             auto oldestInstance = instances.find(oldestInstanceId);
    //             if (oldestInstance != instances.end()) {
    //                 // oldestInstanceId的析构函数里有做destroyWindow逻辑
    //                 instances.erase(oldestInstanceId);
    //             }
    //         }
    //     }
    // public:
    //     PlayerManager(const PlayerManager&) = delete;
    //     PlayerManager& operator=(const PlayerManager&) = delete;

    //     static napi_value Initialize(napi_env env, napi_callback_info info);
    //     static napi_value Start(napi_env env, napi_callback_info info);
    //     static napi_value Pause(napi_env env, napi_callback_info info);
    //     static napi_value Kill(napi_env env, napi_callback_info info);
    //     static napi_value Resume(napi_env env, napi_callback_info info);
    //     static napi_value Seek(napi_env env, napi_callback_info info);
    //     static napi_value SwipeUp(napi_env env, napi_callback_info info);
    //     static napi_value SwipeDown(napi_env env, napi_callback_info info);

    //     static PlayerManager& getInstance() {
    //         static std::mutex mutex;
    //         std::lock_guard<std::mutex> lock(mutex);
    //         static std::unique_ptr<PlayerManager> instancePtr;
    //         if (!instancePtr) {
    //             instancePtr.reset(new PlayerManager());
    //         }
    //         return *instancePtr;
    //     }
    //
    //     std::shared_ptr<Player> CreatePlayer(SampleInfo& sampleInfo) {
    //         int newInstanceId = generateNewInstanceId();
    //         auto player = std::make_shared<Player>(newInstanceId);
    //         player->Init(sampleInfo);
    //         instances[newInstanceId] = player;
    //         currentInstanceId = newInstanceId;
    //         manageInstanceLimit();
    //         return player;
    //     }
    //
    //     int32_t Start() {
    //         if (currentInstanceId != -1) {
    //             return instances[currentInstanceId]->Start();
    //         }
    //         return AVCODEC_SAMPLE_ERR_ERROR;
    //     }
    //
    //     int32_t Pause() {
    //         if (currentInstanceId != -1) {
    //             return instances[currentInstanceId]->Pause();
    //         }
    //         return AVCODEC_SAMPLE_ERR_ERROR;
    //     }
    //
    //     int32_t Resume() {
    //         if (currentInstanceId != -1) {
    //             return instances[currentInstanceId]->Resume();
    //         }
    //         return AVCODEC_SAMPLE_ERR_ERROR;
    //     }
    //
    //     int32_t Seek(int64_t position) {
    //         if (currentInstanceId != -1) {
    //             return instances[currentInstanceId]->Seek(position);
    //         }
    //         return AVCODEC_SAMPLE_ERR_ERROR;
    //     }
    //
    //     int32_t WaitForDone() {
    //         if (currentInstanceId != -1) {
    //             return instances[currentInstanceId]->WaitForDone();
    //         }
    //         return AVCODEC_SAMPLE_ERR_ERROR;
    //     }
    //
    //     void Kill() {
    //         if (currentInstanceId != -1) {
    //             instances[currentInstanceId]->Kill();
    //         }
    //     }
    //
    //     void SwipeUp(SampleInfo &sampleInfo) {
    //         if (currentInstanceId != -1) {
    //             cacheInstance(currentInstanceId);
    //         }
    //         auto newInstance = CreatePlayer(sampleInfo);
    //         currentInstanceId = newInstance->GetInstanceId();
    //         currentWindow = sampleInfo.window;
    //     }
    //
    //     void SwipeDown(SampleInfo &sampleInfo) {
    //         std::lock_guard<std::mutex> lock(mutex);
    //         if (currentInstanceId != -1) {
    //             cacheInstance(currentInstanceId);
    //         }
    //         currentInstanceId = GetPreviousInstanceId();
    //         if (currentInstanceId != -1) {
    //             auto player = instances[currentInstanceId];
    //             player->Resume();
    //             player->SetSurfaceAndDestroyOldOne(sampleInfo.window);
    //             currentWindow = sampleInfo.window;
    //             instances[currentInstanceId] = std::move(player);
    //             cache.erase(currentInstanceId);
    //         } else{
    //             AVCODEC_SAMPLE_LOGI("没有可以恢复的实例");
    //         }
    //     }

    //     PlayerManager()
    //     {
    // //         srand(static_cast<unsigned>(time(0))); // 初始化随机种子
    //         std::random_device rd;
    //         gen = std::mt19937(rd());
    //         dis = std::uniform_int_distribution<>{1, 10000}; // 根据需要调整范围
    //         if (usedInstanceIds.empty()) {
    //             int initialId = generateNewInstanceId();
    //             auto initialPlayer = std::make_shared<Player>(initialId);
    //             instances[initialId] = initialPlayer;
    //             currentInstanceId = initialId;
    //         }
    //     }
    //     static PlayerManager& getInstance() {
    //         static std::mutex mutex;
    //         std::lock_guard<std::mutex> lock(mutex);
    //         static std::unique_ptr<PlayerManager> instancePtr;
    //         if (!instancePtr) {
    //             instancePtr.reset(new PlayerManager());
    //         }
    //         return *instancePtr;
    //     }
    //     static napi_value Initialize(napi_env env, napi_callback_info info);
    //     static napi_value Start(napi_env env, napi_callback_info info);
    //     static napi_value Pause(napi_env env, napi_callback_info info);
    //     static napi_value Kill(napi_env env, napi_callback_info info);
    //     static napi_value Resume(napi_env env, napi_callback_info info);
    //     static napi_value Seek(napi_env env, napi_callback_info info);
    //     static napi_value SwipeUp(napi_env env, napi_callback_info info);
    //     static napi_value SwipeDown(napi_env env, napi_callback_info info);
    //     static napi_value StartInstance(napi_env, napi_callback_info info);
    // public:
    //     std::shared_ptr<Player> getCurrentPlayerInstance() const {
    //         std::shared_lock<std::shared_mutex> lock(cacheMutex_);
    //         return currentInstanceId != -1 ? instances.at(currentInstanceId) : nullptr;
    //     }
    //
    //     OHNativeWindow* getCurrentWindow() const {
    //         std::shared_lock<std::shared_mutex> lock(cacheMutex_);
    //         return currentWindow;
    //     }
    //
    //     // 设置当前窗口
    //     void setWindow(OHNativeWindow* window) {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         if (currentWindow != window) {
    //             // 销毁之前的窗口
    //             if (currentWindow) {
    //                 destroyWindow(currentWindow);
    //             }
    //             currentWindow = window;
    //         }
    //     }
    //
    //     int32_t switchInstance(int newInstanceId, SampleInfo &sampleInfo) {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         if (currentInstanceId != newInstanceId) {
    //             if (currentInstanceId != -1) {
    //                 instances[currentInstanceId]->Pause();
    //                 cacheInstance(currentInstanceId);
    //             }
    //             auto cachedInstance = cache.find(newInstanceId);
    //             if (cachedInstance != cache.end()) {
    //                 instances[newInstanceId] = cachedInstance->second;
    //                 cache.erase(cachedInstance);
    //             } else {
    // //                 int newId = generateNewInstanceId();
    // //                 auto newInstance = std::make_shared<Player>(newId);
    // //                 instances[newId] = newInstance;
    //                 instances[newInstanceId] = nullptr;
    // //                 newInstanceId = newId;
    //                 AVCODEC_SAMPLE_LOGI("Player %{public}i not found in cache, creating new one.", newInstanceId);
    //             }
    //             instances[currentInstanceId]->Init(sampleInfo);
    //             currentInstanceId = newInstanceId;
    // //             if (instances.count(currentInstanceId) == 0) {
    // //                 // Create a new player instance if not found in cache
    // //                 int newId = generateNewInstanceId();
    // //                 auto newInstance = std::make_shared<Player>(newId);
    // //                 instances[newId] = newInstance;
    // //             }
    //         }
    //         return AVCODEC_SAMPLE_ERR_OK;
    //     }
    //
    //     int32_t SwipeUp(SampleInfo &sampleInfo) {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         int newInstanceId = generateNewInstanceId();
    //         auto newInstance = std::make_shared<Player>(newInstanceId);
    //         instances[newInstanceId] = newInstance;
    //         setWindow(sampleInfo.window);
    //         switchInstance(newInstanceId,sampleInfo);
    //     }
    //
    //     int32_t StartCurrentInstance() {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         if (currentInstanceId != -1) {
    //             instances[currentInstanceId]->Start();
    //             return AVCODEC_SAMPLE_ERR_OK;
    //         }
    //         return AVCODEC_SAMPLE_ERR_ERROR; // 如果没有活跃实例，返回错误
    //     }
    //
    //     int32_t GetPreviousInstanceId() {
    //         if (!instanceUsageOrder.empty()) {
    //             int previousInstanceId = instanceUsageOrder.back();
    //             instanceUsageOrder.pop_back();
    //             return previousInstanceId;
    //         }
    //         return AVCODEC_SAMPLE_ERR_ERROR;
    //     }
    //
    //     void SwipeDown() {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         if (currentInstanceId != -1) {
    //             cacheInstance(currentInstanceId);
    //             if(currentWindow) {
    //                 destroyWindow(currentWindow);
    //             }
    //             int32_t previousInstanceId = GetPreviousInstanceId();
    //             if (previousInstanceId != AVCODEC_SAMPLE_ERR_ERROR) {
    //                 currentInstanceId = previousInstanceId;
    //                 instances[currentInstanceId]->
    //             }
    //         }
    //         checkCacheSize();
    //         if(currentWindow) {
    //             destroyWindow(currentWindow);
    //             currentWindow = nullptr;
    //         }
    //     }
    //
    //     ~PlayerManager() {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         instances.clear();
    //         cache.clear();
    //         usedInstanceIds.clear();
    //     }
    // private:
    //     static const int MAX_CACHE_SIZE = 6;
    //     std::map<int, std::shared_ptr<Player>> instances;
    //     std::map<int, std::shared_ptr<Player>> cache;
    //     std::list<int> instanceUsageOrder;
    //     std::set<int> usedInstanceIds;
    //     int currentInstanceId = -1;
    //     mutable std::shared_mutex cacheMutex_;
    //     OHNativeWindow* currentWindow = nullptr;
    //
    //     // 随机数生成器
    //     /*
    //         std::random_device 用于获取随机数种子。
    //         std::mt19937 是一个高质量的随机数生成器，使用 std::random_device 作为种子。
    //         std::uniform_int_distribution<> 用于生成均匀分布的随机整数。
    //     */
    //     std::random_device rd;
    //     std::mt19937 gen{rd()};
    //     std::uniform_int_distribution<> dis;
    //
    //     int generateNewInstanceId() {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         int newId;
    //         do {
    // //             newId = std::rand();
    //             newId = dis(gen);
    //         } while (usedInstanceIds.find(newId) != usedInstanceIds.end());
    //         usedInstanceIds.insert(newId);
    //         return newId;
    //     }
    //
    //     void cacheInstance(int id) {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         auto instance = instances.find(id);
    //         if (instance != instances.end()) {
    //             instanceUsageOrder.push_back(id);
    //             cache[id] = instance->second;
    //             instances.erase(instance);
    //         }
    //     }
    //
    //     void checkCacheSize() {
    //         std::lock_guard<std::shared_mutex> lock(cacheMutex_);
    //         while (cache.size() > static_cast<size_t>(MAX_CACHE_SIZE)) {
    //             int oldestId = instanceUsageOrder.front();
    //             instanceUsageOrder.pop_front();
    //             cache.erase(oldestId);
    //             AVCODEC_SAMPLE_LOGI("Evicted player %{public}i from cache.", oldestId);
    //         }
    //     }
    //
    //     void destroyWindow(OHNativeWindow* window) {
    //         OH_NativeWindow_DestroyNativeWindow(window);
    //     }
};

#endif // PLAYER_MANAGER_H
